#pragma once

#include "kernel/task/task_types.h"
#include "kernel/agv/agv_entity.h"
#include "kernel/interfaces/ILogger.h"
#include <memory>
#include <string>
#include <vector>
#include <optional>

namespace application {
namespace area { class Area; }
namespace charge { class ChargePoint; }
namespace park { class ParkPoint; }
namespace lift { class BaseLift; }
namespace task {

/**
 * @brief 任务上下文 - 任务间共享的数据
 */
struct TaskContext {
    // AGV实体指针
    kernel::agv::AgvEntity* agv{nullptr};

    // 当前地图名称
    std::string currentMap;

    // 错误消息
    std::string errorMessage;

    // 任务ID（用于日志和追踪）
    std::string taskId;

    // 任务链ID
    std::string chainId;

    // 状态请求（子任务向执行器发起）
    std::optional<kernel::task::TaskChainStatus> statusRequest;
    int suspendCountRequest{0};
    bool dispatcherMoveRequested{false};
    std::string dispatcherMidMoveStation;

    // 资源句柄
    std::vector<std::weak_ptr<area::Area>> occupiedAreas;
    std::weak_ptr<charge::ChargePoint> chargePoint;
    std::weak_ptr<park::ParkPoint> parkPoint;
    std::weak_ptr<lift::BaseLift> liftHandle;

    // 清空错误消息
    void clearError() {
        errorMessage.clear();
    }

    // 设置错误消息
    void setError(const std::string& error) {
        errorMessage = error;
    }

    // 检查是否有错误
    bool hasError() const {
        return !errorMessage.empty();
    }

    // 请求任务链状态变更
    void requestStatus(kernel::task::TaskChainStatus status, int suspendCount = 0) {
        statusRequest = status;
        suspendCountRequest = suspendCount;
        if (status != kernel::task::TaskChainStatus::DispatcherMove) {
            dispatcherMoveRequested = false;
            dispatcherMidMoveStation.clear();
        }
    }

    // 请求调度移动至指定站点
    void requestDispatcherMove(const std::string& midStation) {
        statusRequest = kernel::task::TaskChainStatus::DispatcherMove;
        dispatcherMoveRequested = true;
        dispatcherMidMoveStation = midStation;
    }

    // 清除状态请求（由执行器调用）
    void clearStatusRequest() {
        statusRequest.reset();
        suspendCountRequest = 0;
        dispatcherMoveRequested = false;
        dispatcherMidMoveStation.clear();
    }

    // 记录占用区域
    void addOccupiedArea(const std::shared_ptr<area::Area>& area) {
        if (!area) {
            return;
        }
        for (const auto& weak : occupiedAreas) {
            if (auto existing = weak.lock()) {
                if (existing.get() == area.get()) {
                    return;
                }
            }
        }
        occupiedAreas.emplace_back(area);
    }

    void clearOccupiedAreas() {
        occupiedAreas.clear();
    }

    void setChargePoint(const std::shared_ptr<charge::ChargePoint>& point) {
        chargePoint = point;
    }

    void clearChargePoint() {
        chargePoint.reset();
    }

    void setParkPoint(const std::shared_ptr<park::ParkPoint>& point) {
        parkPoint = point;
    }

    void clearParkPoint() {
        parkPoint.reset();
    }

    void setLiftHandle(const std::shared_ptr<lift::BaseLift>& lift) {
        liftHandle = lift;
    }

    void clearLiftHandle() {
        liftHandle.reset();
    }
};

/**
 * @brief 子任务基类 - 应用层任务执行的基础单元
 * @details 所有子任务（Move, Jack, Charge等）的基类
 *          实现状态机模式: Init → Running → Cleanup → Finished
 */
class SubTaskBase {
public:
    explicit SubTaskBase(std::shared_ptr<kernel::ILogger> logger);
    virtual ~SubTaskBase() = default;

    /**
     * @brief 初始化阶段
     * @param ctx 任务上下文
     * @return 下一个阶段
     */
    virtual kernel::task::TaskStage init(TaskContext& ctx) = 0;

    /**
     * @brief 运行阶段（循环调用）
     * @param ctx 任务上下文
     * @return 下一个阶段
     */
    virtual kernel::task::TaskStage run(TaskContext& ctx) = 0;

    /**
     * @brief 清理阶段
     * @param ctx 任务上下文
     * @return 下一个阶段
     */
    virtual kernel::task::TaskStage cleanup(TaskContext& ctx) = 0;

    /**
     * @brief 执行子任务（外部调用）
     * @param ctx 任务上下文
     * @return 当前阶段
     */
    kernel::task::TaskStage execute(TaskContext& ctx);

    /**
     * @brief 重置子任务状态
     */
    void reset();

    /**
     * @brief 获取当前阶段
     */
    kernel::task::TaskStage getStage() const { return m_stage; }

    /**
     * @brief 获取任务类型
     */
    virtual kernel::task::TaskType getType() const = 0;

    /**
     * @brief 获取任务描述（用于日志）
     */
    virtual std::string getDescription() const = 0;

    /**
     * @brief 强制执行清理逻辑（幂等）
     */
    void forceCleanup(TaskContext& ctx);

    /**
     * @brief 判断清理是否已经执行
     */
    bool isCleanupDone() const { return m_cleanupDone; }

protected:
    // 当前执行阶段
    kernel::task::TaskStage m_stage{kernel::task::TaskStage::Init};

    // 日志接口
    std::shared_ptr<kernel::ILogger> m_logger;
    bool m_cleanupDone{false};

    /**
     * @brief 辅助方法：记录错误并返回Finished阶段
     */
    kernel::task::TaskStage finishWithError(
        TaskContext& ctx,
        const std::string& error
    );

    /**
     * @brief 辅助方法：记录信息日志
     */
    void logInfo(const std::string& message);

    /**
     * @brief 辅助方法：记录调试日志
     */
    void logDebug(const std::string& message);

    /**
     * @brief 辅助方法：记录错误日志
     */
    void logError(const std::string& message);

    /**
     * @brief 辅助方法：记录警告日志
     */
    void logWarning(const std::string& message);
};

} // namespace task
} // namespace application
